using System;
using System.Threading.Tasks;
using Windows.Foundation.Collections;
using Windows.Storage.Streams;
using Windows.Web.Http;
using Windows.Web.Http.Headers;
using Debug = Network.Diagnostics.Debug;

namespace Network.Http
{
    public static class HttpRequest
    {
        public delegate void NetworkEventHandler();
        public static event NetworkEventHandler NetworkDisconnected;

        public static async Task<string> Post(string host, string body)
        {
            return await PostAsync(host, null, null, body);
        }

        public static async Task<string> PostAsync(string host, string tokenType, string token, string body)
        {
            Debug.WriteLine($"HttpRequest Post - host:{host}, body:{body}");
            HttpClient httpClient = new HttpClient();
            if (!string.IsNullOrEmpty(tokenType) && !string.IsNullOrEmpty(token))
            {
                httpClient.DefaultRequestHeaders.Authorization = new HttpCredentialsHeaderValue(tokenType, token);
            }

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, new Uri(host))
            {
                Content = new HttpStringContent(body, UnicodeEncoding.Utf8, "application/json")
            };
            request.Content.Headers.ContentType = new HttpMediaTypeHeaderValue("application/json");

            var result = await SendHttpRequest(httpClient, request);
            Debug.WriteLine($"HttpRequest Post, Res:{result}");
            return result;
        }

        public static async Task<string> Post(string host, string token, IRandomAccessStream stream)
        {
            //Debug.WriteLine($"HttpRequest Post - host:{host}, token:{token}");
            HttpClient httpClient = new HttpClient();
            //if (!string.IsNullOrEmpty(tokenType) && !string.IsNullOrEmpty(token))
            //{
            //    //httpClient.DefaultRequestHeaders.Authorization = new HttpCredentialsHeaderValue(tokenType, token);
            //}

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, new Uri(host))
            {
                Content = new HttpStreamContent(stream),
            };
            request.Content.Headers.ContentType = new HttpMediaTypeHeaderValue("application/octet-stream");
            request.Headers.Add("Auth", token);

            var result = await SendHttpRequest(httpClient, request);
            //Debug.WriteLine($"HttpRequest Post, Res:{result}");
            return result;
        }

        public static async Task<string> GetAsync(string host, string tokenType, string token, ValueSet parameter = null)
        {
            HttpClient httpClient = new HttpClient();

            if (!string.IsNullOrEmpty(tokenType) && !string.IsNullOrEmpty(token))
            {
                httpClient.DefaultRequestHeaders.Authorization = new HttpCredentialsHeaderValue(tokenType, token);
            }

            string paramString = ValueSetToString(parameter);

            if (!string.IsNullOrEmpty(paramString))
            {
                host = host + "?" + paramString;
            }

            Debug.WriteLine($"HttpRequest Get - host:{host}");
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(host));

            var result = await SendHttpRequest(httpClient, request);
            Debug.WriteLine($"HttpRequest Get, Res:{result}");

            return result;
        }

        private static string ValueSetToString(ValueSet parameter)
        {
            if (parameter == null) return null;

            string paramString = "";

            int paramCount = 0;
            foreach (var p in parameter)
            {
                if (p.Value == null)
                {
                    paramString = p.Key;
                }
                else
                {
                    paramString =paramString+ p.Key + "=" + p.Value;
                }
                paramCount++;
                if (paramCount < parameter.Count)
                {
                    paramString += "&";
                }
            }

            return paramString;
        }

        private static async Task<string> SendHttpRequest(HttpClient client, HttpRequestMessage request)
        {
            HttpResponseMessage httpResponse = new HttpResponseMessage();

            try
            {
                httpResponse = await client.SendRequestAsync(request);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                NetworkDisconnected?.Invoke();
                return "";
            }

            string responseBody = "";

            Debug.WriteLine($"SendHttpRequest.StatusCode:{httpResponse.StatusCode}, IsSuccessStatusCode:{httpResponse.IsSuccessStatusCode}");
            responseBody = await httpResponse.Content.ReadAsStringAsync();
            return responseBody;
        }
    }
}
